import * as THREE from 'three';
import { Water, WaterOptions } from 'three/examples/jsm/objects/Water2';
import floor from '../../../textures/floors/FloorsCheckerboard_S_Diffuse.jpg';
import waterNormals1 from '../../../textures/water/Water_1_M_Normal.jpg';
import waterNormals2 from '../../../textures/water/Water_2_M_Normal.jpg';
import BaseScene, { SceneConfig } from '../../components/scenes/BaseScene'

export class WaterRender extends BaseScene {
  water: Water;

  constructor(config) {
    super(config);
    this.addWater();
    this.addBox();
  }

  private addWater() {
    const box = new THREE.PlaneBufferGeometry(100, 100);
    const option: WaterOptions = {
      scale: 2,
      color: 0xfff000,
      textureWidth: 1024,
      textureHeight: 1024,
      flowDirection: new THREE.Vector2(1, 10),
      normalMap0: new THREE.TextureLoader().load(waterNormals1),
      normalMap1: new THREE.TextureLoader().load(waterNormals2),
    };
    this.water = new Water(box, option);
    this.water.position.y = 1;
    this.water.rotation.x = -Math.PI / 2;
    this.scene.add(this.water);
    return this.water;
  }

  private addBox() {
    const boxGeometry = new THREE.BoxGeometry(100, 100, 100, 50, 50, 50);
    const boxMaterial = new THREE.MeshBasicMaterial({
      color: 0xcccccc,
      side: THREE.BackSide,
    });
    const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);
    boxMesh.position.y = -10;
    boxMesh.rotation.x = -Math.PI / 2;

    const textureLoader = new THREE.TextureLoader();
    textureLoader.load(floor, function (map) {
      map.wrapS = THREE.RepeatWrapping;
      map.wrapT = THREE.RepeatWrapping;
      map.anisotropy = 16;
      map.repeat.set(1, 1);
      boxMaterial.map = map;
      boxMaterial.needsUpdate = true;
    });
    this.scene.add(boxMesh);
  }
}
export const waterRender = (config: SceneConfig ): WaterRender => {
  const renderWater = new WaterRender(config);
  renderWater.run();
  return renderWater;
};
